package com.opc.quarz;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.opc.Mapper.*;
import com.opc.Pojo.Car;
import com.opc.Pojo.SampleScrew;
import com.opc.Pojo.Screw;
import com.opc.Service.CarService;
import com.opc.Service.CarStatusService;
import com.opc.properties.CarTypeProperties;
import com.opc.properties.FrequencyProperties;
import com.opc.websocket.WebSocketServer;
import lombok.extern.slf4j.Slf4j;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.quartz.QuartzJobBean;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Component
@DisallowConcurrentExecution // 确保任务不会并发执行
@Slf4j
public class SampledData8 extends QuartzJobBean {
    @Value("${historyData.path}")//必须是org.springframework.beans.factory.annotation提供的Value
    private String basePath;
    @Autowired
    private FrequencyProperties frequencyProperties;
    @Autowired
    private CarTypeProperties carTypeProperties;
    @Autowired
    private ScrewMapper screwMapper;
    @Autowired
    private CarMapper carMapper;
    @Autowired
    private WebSocketServer webSocketServer;
//    @Qualifier("carStatusService")
    @Autowired
    private CarStatusService carStatusService;
//    @Qualifier("carService")
    @Autowired
    private CarService carService;
//    @Qualifier("workingPositionService")
    @Autowired
    private SampleScrewMapper sampleScrewMapper;
    @Autowired
    private ScrewTypeMapper screwTypeMapper;

    private static String convertLocalDateTimeToString(Date Time) {
        LocalDateTime localDateTime = Time.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
        String formattedTime = String.format("%04d:%02d:%02d:%02d:%02d:%02d",
                localDateTime.getYear(),
                localDateTime.getMonthValue(),
                localDateTime.getDayOfMonth(),
                localDateTime.getHour(),
                localDateTime.getMinute(),
                localDateTime.getSecond());
//        log.info("formattedTime是"+formattedTime);
        // 使用 replace() 方法替换第一个 ':' 为 '-'
        // 使用正则表达式替换前两个 ':' 为 '-'
        // 拆分字符串
        String[] parts = formattedTime.split(":");
        // 重新组装字符串
        String newFormattedTime = String.join("-", parts[0], parts[1]) + "-" + parts[2] + " " + parts[3] + ":" + parts[4] + ":" + parts[5];
//        log.info("timeFormatter是"+newFormattedTime);
        return newFormattedTime;
    }

    private void createDirectoryIfNotExists(String directoryPath) {
        Path path = Paths.get(directoryPath);
        // 检查目录是否存在
        if (!Files.exists(path)) {
            try {
                // 创建目录（包括必要的父目录）
                Files.createDirectories(path);
                log.info("目录已创建: " + directoryPath);
            } catch (IOException e) {
                System.err.println("无法创建目录: " + e.getMessage());
                if(e.getMessage().contains("Unable to determine if root directory exists")){
                    log.info("创建文件夹失败，没有这个盘");
                    Map map = new HashMap<>();
                    int colonIndex = basePath.indexOf(':');
                    if (colonIndex != -1) {
                        String result = basePath.substring(0, colonIndex);
                        map.put("message", "创建备份目录失败，找不到磁盘"+result);
                    }
                    String json = JSON.toJSONString(map);
                    webSocketServer.sendToAllClient(json);
                }
            }
        } else {
            log.info("目录已存在: " + directoryPath);
        }
    }

    @Override
    @Transactional
    @Async
    public void executeInternal(JobExecutionContext context) {
        // 获取当前日期
        LocalDate today = LocalDate.now();
        // 获取前一日
        LocalDate previousDay = today.minusDays(1);
        // 打印前一日
        //log.info("前一日是：" + previousDay);
        //System.out.println("前一日是：" + previousDay);
        String day0 = today.toString();
        String day = previousDay.toString();

        LambdaQueryWrapper<SampleScrew> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(SampleScrew::getCreateTime, day0);
        List<SampleScrew> sampleScrews = sampleScrewMapper.selectList(queryWrapper);
        //System.out.println("sampleScrews是"+sampleScrews);
        if (!sampleScrews.isEmpty()) {
            //System.out.println("昨日螺丝数据已取样");
            //log.info("昨日螺丝数据已取样");//是今日取的
            return;
        }
        LambdaQueryWrapper<Car> queryCar0Wrapper = new LambdaQueryWrapper<>();
//        queryCar0Wrapper.like(Car::getCreateTime, day);
//        queryCar0Wrapper.eq(Car::getCarType, carTypeProperties.getCamry()).or()
//                .eq(Car::getCarType, carTypeProperties.getLevin());
        queryCar0Wrapper.like(Car::getCreateTime, day)
                .and(i -> i.eq(Car::getCarType, carTypeProperties.getCamry())
                        .or()
                        .eq(Car::getCarType, carTypeProperties.getLevin()));
        List<Car> Cars = carMapper.selectList(queryCar0Wrapper);
        if (Cars.isEmpty()) {
            //log.info("昨日没有相关车型数据");
            //System.out.println("昨日没有相关车型数据");
            return;
        }else{
            //System.out.println("昨日有相关车型数据");
            List<Long> carIds = Cars.stream().map(Car::getId)
                    .collect(Collectors.toList());
            //System.out.println("carIds是：" + carIds);

            LambdaQueryWrapper<Screw> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(Screw::getCarId, carIds);
            List<Screw> screwList = screwMapper.selectList(wrapper);
            //System.out.println("screwList是：" + screwList);
            if(screwList.isEmpty()){
                //log.info("昨日螺丝数据为空");
                //System.out.println("昨日螺丝数据为空");
                return;
            }
        }

        // 分别处理凯美瑞和雷凌车型
        for (String carType : Arrays.asList(carTypeProperties.getCamry(),
                carTypeProperties.getLevin())) {
            // 查询前一天的特定车型的车辆
            LambdaQueryWrapper<Car> queryCarWrapper = new LambdaQueryWrapper<>();
            queryCarWrapper.like(Car::getCreateTime, day);
            queryCarWrapper.eq(Car::getCarType, carType);
            List<Car> carList = carMapper.selectList(queryCarWrapper);
            //log.info("carType是:"+carType);
            //log.info("carList.size()是："+carList.size());
            if (carList.isEmpty()) {
                //System.out.println("没有找到昨天的" + carType + "车型");
                log.info("没有找到昨天的" + carType + "车型");
                continue; // 继续处理下一个车型
            }

            List<Long> carIds = carList.stream().map(Car::getId).toList();

            int batchSize = frequencyProperties.getSampleDataFrequency(); // 每批处理的车辆ID数量
            int totalCars = carIds.size(); // 总车辆数

// 只处理前8批车辆ID，确保不会处理超过前8批的车辆ID(取多一批，防止数据不够)
            for (int i = 0; i < 9; i++) {
                // 计算当前需要处理的车辆ID的索引
                int index = i * batchSize;
                // 确保索引不会超出车辆ID列表的范围
                if (index < totalCars) {
                    Long carId = carIds.get(index);
                    log.info("正在处理车辆ID: " + carId);

                    // 为当前车辆ID查询对应的螺丝
                    LambdaQueryWrapper<Screw> queryScrewWrapper = new LambdaQueryWrapper<>();
                    queryScrewWrapper.eq(Screw::getCarId, carId);
                    List<Screw> screwList = screwMapper.selectList(queryScrewWrapper);
                    for (Screw screw : screwList) {
                        SampleScrew sampleScrew = new SampleScrew();
                        sampleScrew.setScrewTypeId(screw.getScrewTypeId());
                        sampleScrew.setCarType(carType);
                        sampleScrew.setCarNum(String.valueOf(screw.getCarId()));
                        sampleScrew.setTorque(screw.getTorque());
                        sampleScrew.setScrewCreateTime(screw.getCreateTime());
                        sampleScrew.setUnit(screw.getUnit());
                        sampleScrewMapper.insert(sampleScrew);//saveBatch
                    }
                } else {
                    // 如果索引超出范围，说明没有足够的车辆ID进行处理
                    log.info("没有足够的车辆ID进行处理");
                    //System.out.println("没有足够的车辆ID进行处理");
                    break;
                }
            }


//            int batchSize = frequencyProperties.getSampleDataFrequency(); // 每批处理的车辆ID数量
//            int totalBatches = carIds.size() / batchSize; // 总批次数
//
//            // 只处理前8批车辆ID，确保不会处理超过前8批的车辆ID（抽多一组，防止数据不够）
//            for (int batch = 0; batch < Math.min(9, totalBatches); batch++) {
//                log.info("正在处理第" + (batch + 1) + "批车辆ID...");
//                // 计算当前批次的起始索引
//                int startIndex = batch * batchSize;
//                // 获取当前批次的车辆ID子列表
//                List<Long> subCarIds = carIds.subList
//                        (startIndex, Math.min(startIndex + batchSize, carIds.size()));
//
//                // 为当前批次的每个车辆ID查询对应的螺丝
//                for (Long carId : subCarIds) {
//                    LambdaQueryWrapper<Screw> queryScrewWrapper = new LambdaQueryWrapper<>();
//                    queryScrewWrapper.eq(Screw::getCarId, carId);
//                    List<Screw> screwList = screwMapper.selectList(queryScrewWrapper);
//                    for (Screw screw : screwList) {
//                        SampleScrew sampleScrew = new SampleScrew();
//                        sampleScrew.setScrewTypeId(screw.getScrewTypeId());
//                        sampleScrew.setCarType(carType);
//                        sampleScrew.setTorque(screw.getTorque());
//                        sampleScrew.setUnit(screw.getUnit());
//                        sampleScrewMapper.insert(sampleScrew);//saveBatch
//                    }
//                }
//            }
        }
        log.info("已完成对昨天"+ carTypeProperties.getCamry()+
                "和"+carTypeProperties.getLevin()+"螺丝数据的取样");
    }

//    public void executeInternal(JobExecutionContext context) {
//        // 获取当前日期
//        LocalDate today = LocalDate.now();
//        // 获取前一日
//        LocalDate previousDay = today.minusDays(1);
//        // 打印前一日
//        log.info("前一日是：" + previousDay);
//        String day = previousDay.toString();
//        //从前一天的凯美瑞车型的螺丝里每隔50台车取8粒放进数据库
//        LambdaQueryWrapper<Car> queryCarWrapper = new LambdaQueryWrapper<>();
//        queryCarWrapper.like(Car::getCreateTime, day);
//        queryCarWrapper.eq(Car::getCarType, carTypeProperties.getCamry())
//                .or().eq(Car::getCarType, carTypeProperties.getLevin());//"381D"
//        //取出所有凯美瑞的车的id列表
//        List<Car> carList = carMapper.selectList(queryCarWrapper);
//
//        if(carList.isEmpty()){
//            log.info("没有找到昨天的凯美瑞和雷凌的车型");
//            return;
//        }
//        List<Long> carIds = carList.stream().map(Car::getId).toList();
//        //根据carIds每隔50台取出一台车对应的所有螺丝，取两次，刚好8颗(螺丝对象screw有个carId外键)
//
//        int batchSize = frequencyProperties.getSampleDataFrequency(); // 每批处理的车辆ID数量
//        int totalBatches = carIds.size() / batchSize; // 总批次数
//
//// 只处理前8批车辆ID，确保不会处理超过前8批的车辆ID
//        for (int batch = 0; batch < Math.min(8, totalBatches); batch++) {
//            // 计算当前批次的起始索引
//            int startIndex = batch * batchSize;
//            // 获取当前批次的车辆ID子列表
//            List<Long> subCarIds = carIds.subList(startIndex, Math.min(startIndex + batchSize, carIds.size()));
//
//            // 为当前批次的每个车辆ID查询对应的螺丝
//            for (Long carId : subCarIds) {
//                LambdaQueryWrapper<Screw> queryScrewWrapper = new LambdaQueryWrapper<>();
//                queryScrewWrapper.eq(Screw::getCarId, carId);
//                List<Screw> screwList = screwMapper.selectList(queryScrewWrapper);
//                for (Screw screw : screwList) {
//                    SampleScrew sampleScrew = new SampleScrew();
//                    sampleScrew.setScrewTypeId(screw.getScrewTypeId());
//                    sampleScrew.setCarType(carTypeProperties.getCamry());
//                    sampleScrew.setTorque(screw.getTorque());
//                    sampleScrew.setUnit(screw.getUnit());
//                    sampleScrewMapper.insert(sampleScrew);//saveBatch
//                }
//
//            }
//        }
//        log.info("今日已完成对昨天螺丝数据的取样");
//    }
}
